package com.web.controller.pay;

import com.web.annotation.CurrentUser;
import com.web.annotation.LoginRequired;
import com.web.config.PayConfiguration;
import com.web.domain.Response;
import com.web.entity.*;
import com.web.service.LoginService;
import com.web.service.VipService;
import com.web.utils.DoubleUtil;
import com.xkk.utils.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

@Slf4j
@RestController
@RequestMapping(value = "/app")
public class PayController {
    @Autowired
    private PayConfiguration payConfiguration;
    @Autowired
    private VipService vipService;
    @Autowired
    private LoginService loginService;

    @RequestMapping("/open/pay/ali/notify")
    @ResponseBody
    @LoginRequired
    @Transactional
    public String ali_notify(HttpServletRequest request) {
        AliPayDto aliPayDto = new AliPayDto();
        aliPayDto.setMap(RequestUtil.getParams(request));
        if (aliPayDto.getMap() == null || aliPayDto.getMap().isEmpty()) {
            log.warn("ali notify accept error->map is blank");
            return "";
        }
        aliPayDto.setPayAppid(payConfiguration.getAli().getAppid());
        aliPayDto.setPayUrl(payConfiguration.getAli().getUrl());
        aliPayDto.setPaySelfSecret(payConfiguration.getAli().getSelfSecret());
        aliPayDto.setPayPublicSecret(payConfiguration.getAli().getPublicSecret());
        aliPayDto.setPayPublicSecret2(payConfiguration.getAli().getPublicSecret2());
        PayResponse payResponse = AliPayManage.mg.aliValid(aliPayDto);

        if (payResponse.isOk()) {
            Map<String, String> payMap = (Map) payResponse.getParams();
            //{"gmt_create":"2017-07-07 18:09:33","charset":"utf-8","seller_email":"ukufew5889@sandbox.com",
            // "open_id":"20880023683944814295949620412504","subject":"test",
            // "sign":"sYIYGrNJUzKSV5PHh9W6tuT3IrKaM/g/LtZTRC1nIwcqA+jXY5PMAHRwXxB4nfU8yXOcCODaihuu+tuPdFRfGQP61hMS9Tdoqq6fgeK6GFNFOHlTnTxXSHk7YFBAINlAvriFyOrPCnm7LRpJaK0G627d1ZJcKy1fCEFwzzWfqIvtwl6DzpTP68acXLuTdmur41B80S4uLquO3LFHNSV1xzS23jy3r1LqKGPcjDXtbhX+Id2j3pRz+TdhJ1d22mUCd5iD41l1NZP+qFDwyWllx8//VR3e8KWXsVCbFhmEnCnbFWeIOswkDVnSovOPJIbWlXLw39D6fQvSsWPXp/Spow\u003d\u003d",
            // "body":"hello","buyer_id":"2088102172930041","invoice_amount":"1.00",
            // "notify_id":"393fe52fa9110f3a556d4b0d13100fdgb6",
            // "fund_bill_list":"[{"amount":"1.00","fundChannel":"ALIPAYACCOUNT"}]","notify_type":"trade_status_sync",
            // "trade_status":"TRADE_SUCCESS","receipt_amount":"1.00","app_id":"2016080600177824","buyer_pay_amount":"1.00",
            // "sign_type":"RSA2","seller_id":"2088102170153257","gmt_payment":"2017-07-07 18:09:40","notify_time":"2017-07-07 18:09:40",
            // "version":"1.0","out_trade_no":"1499422177097","total_amount":"1.00","trade_no":"2017070721001004040200146814",
            // "auth_app_id":"2016080600177824","buyer_logon_id":"xmo***@sandbox.com","point_amount":"0.00"}
            String trade_no = payMap.get("out_trade_no");
            //trade_status 表示订单交易状态
            String trade_status = payMap.get("trade_status");

            if ("TRADE_SUCCESS".equals(trade_status)) {
                //交易成功
                String payId = payMap.get("out_trade_no");
                log.info(">>>>>>orderId>>>>>>>" + payId);
                String totalPay = payMap.get("total_amount");
                //查询订单
                RMBRecord record = vipService.selectByIdRMB("rmb_id",trade_no);
                //获取个人信息
                UserInfo info = loginService.info("user_id",record.getUserId());
                notifyPay(payId);
                return "success";
            }else{
                return "fall";
            }
        } else {
            log.debug(payResponse.toString());
            log.info("校验失败");
            return "";
        }

    }

    @RequestMapping("/open/pay/wx/notify")
    @ResponseBody
    @LoginRequired
    @Transactional
    public String wx_notify(HttpServletRequest request) {
        String xml = "";
        try {
            xml = IOUtils.toString(request.getInputStream());
            System.out.println(xml);
        } catch (IOException e) {
            log.warn("wx notify accept error->{}", e.getMessage());
        }
        Map<String, String> map = readStringXmlOut(xml);
        WxPayDto wxPayDto = new WxPayDto();
        wxPayDto.setAppid(StringUtils.defaultString(map.get("appid")));
        wxPayDto.setMch_id(StringUtils.defaultString(map.get("mch_id")));
        if (!StringUtils.equals(wxPayDto.getAppid(), payConfiguration.getWx().getAppId())) {
            log.warn("wx notify error->appid不一致");
            return "";
        }
        wxPayDto.setSignKey(payConfiguration.getWx().getSignKey());
        //校验
        PayResponse payResponse = WxPayManage.mg.wxValid(wxPayDto, map);
        if (payResponse.isOk()) {
            //处理逻辑
            Map<String, String> payMap = (Map) payResponse.getParams();
            //获取transaction_id 交易订单号
            String transaction_id = payMap.get("transaction_id");
            String orderId = map.get("out_trade_no");
            String totalPay = map.get("total_fee");
            String tradeStatus = map.get("result_code");
            notifyPay(orderId);
            return "<?xmlversion=\"1.0\"encoding=\"UTF-8\"?><xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

        } else {
            log.warn("wx notify return 处理失败->{}", payResponse.getMessage());
            return "";
        }
    }

    /**
     * @param xml
     * @return Map
     * @description 将xml字符串转换成map
     */
    public static Map<String, String> readStringXmlOut(String xml) {
        Map<String, String> map = new HashMap<String, String>();
        Document doc = null;
        try {
            doc = DocumentHelper.parseText(xml); // 将字符串转为XML
            Element rootElt = doc.getRootElement(); // 获取根节点
            @SuppressWarnings("unchecked")
            List<Element> list = rootElt.elements();// 获取根节点下所有节点
            for (Element element : list) { // 遍历节点
                map.put(element.getName(), element.getText()); // 节点的name为map的key，text为map的value
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    public void notifyPay(String orderId){
        //查询订单
        RMBRecord record = vipService.selectByIdRMB("rmb_id",orderId);
        if (record.getIsPay() == 1){
            return;
        }
        //获取个人信息
        UserInfo info = loginService.info("user_id",record.getUserId());
        //设置订单为已支付状态并更新数据库
        record.setIsPay(1);
        vipService.uploadRMBRecord(record);
        //获取模豆余额
        Integer currency = info.getCurrency();
        if (record != null){
            String type[] = record.getType().split("-");
            System.out.println("-------------"+type.toString()+"----------");
            switch (type[0]){
                case "开通会员":
                    //添加会员
                    vipService.addVIPUserInfo(new VIPUserInfo(record.getUserId(),Integer.valueOf(type[1]),new Date(),new Date()));
                    //查询会员信息
                    VipInfo vipInfo = vipService.selectById("vip_basis_id",type[1]);
                    //插入模豆流水记录
                    loginService.addCurrencyRecord(vipInfo.getVipgive().intValue(),currency,null,info.getUserId(),2,1);
                    //赠送模豆
                    info.setCurrency(currency + vipInfo.getVipgive().intValue());
                    //用户表更新VIP信息
                    info.setIsVip(1);
                    loginService.uploadUserInfo(info);
                    break;
                case "模豆充值":
                    //获取模豆充值基本信息
                    ChargeManageInfo chargeManageInfo = vipService.selectByIdChargeManageInfo("id",type[1]);
                    //插入模豆流水记录
                    loginService.addCurrencyRecord(chargeManageInfo.getSend().intValue(),currency,null,info.getUserId(),3,info.getIsVip());
                    //增加模豆
                    info.setCurrency(currency + chargeManageInfo.getSend().intValue());
                    loginService.uploadUserInfo(info);
                default:
                    break;
            }
        }
    }

}
